package middleware

import (
	"fmt"
	iris_jwt "github.com/iris-contrib/middleware/jwt"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/context"
	"github.com/kataras/iris/v12/middleware/jwt"
	"huanteng/web/global/application"

	"huanteng/web/helpers"
	"time"
)

/*了解如何将任何JWT 3rd-party软件包与Iris结合使用。
我们使用kataras/jwt。
使用以下命令安装：go -u github.com/kataras/jwt
文档：https://github.com/kataras/jwt#table-of-contents
*/
//替换为您自己的密钥，并将其保密。
//“ signatureSharedKey”用于HMAC（HS256）签名算法.

var (
	sigKey = []byte("signature_hmac_secret_shared_key")

	// encKey = []byte("GCM_AES_256_secret_shared_key_32")
)
type fooClaims struct {
	Foo string `json:"foo"`
	Model interface{}
	Id uint
}


func GenerateToken(uid uint,foo string) (token []byte,err error) {
	// NewSigner接受签名算法以及它的（私有或共享）密钥
	//以及生​​成的令牌的最大生存期，并返回JWT签名者。参见其Sign方法。
	//用法：签名者：= NewSigner（HS256，secret，15 * time.Minute）
	//令牌，err：= signer.Sign（userClaims {Username：“ kataras”}）
	//通过以下方式启用有效负载加密：signer.WithEncryption（encKey，nil）
	signer := jwt.NewSigner(jwt.HS256, sigKey, 10*12*time.Minute)
	claims := fooClaims{Foo: foo,Id:uid}

	token, err = signer.Sign(claims)
	if err != nil {
		return
	}

	return

}
func JwtVerifierMiddleware() context.Handler  {
	verifier := jwt.NewVerifier(jwt.HS256, sigKey)

	//启用服务器端令牌块功能（甚至在其到期时间之前）：使用该方法通过ctx.logout可以注销
	verifier.WithDefaultBlocklist()

	//通过以下方式启用有效载荷解密： verifier.WithDecryption（encKey，nil）
	verifyMiddleware := verifier.Verify(func() interface{} {
		return new(fooClaims)
	})
	verifier.ErrorHandler = func(ctx iris.Context, err error) { // app.OnErrorCode(401, ...)
		//ctx.StopWithError(iris.StatusUnauthorized, err)
		if err!=nil{
			//ctx.StopWithError(iris.StatusUnauthorized, err)
			ctx.JSON(helpers.AuthFailedMsg(err.Error()))

		}
	}
	return verifyMiddleware
}




func JwtVerify(foo string) context.Handler {
	return func (ctx iris.Context) {
		//获取经过验证和解码的声明。
		claims := jwt.Get(ctx).(*fooClaims)
		if claims==nil{
			ctx.JSON(helpers.AuthFailedMsg("fuckyou"))
		}
		if claims.Foo!=foo{
			ctx.JSON(helpers.AuthFailedMsg("跨那啥访问不允许"))
		}
		//（可选）如果要使用令牌信息，则获取令牌信息。
		//仅是有关如何检索所有标准声明的示例（由签署者的最大年龄“ exp”设置）。
		/*standardClaims := jwt.GetVerifiedToken(ctx).StandardClaims
		expiresAtString := standardClaims.ExpiresAt().Format(ctx.Application().ConfigurationReadOnly().GetTimeFormat())
		timeLeft := standardClaims.Timeleft()

		ctx.Writef("foo=%s\nexpires at: %s\ntime left: %s\n", claims.Foo, expiresAtString, timeLeft)*/
		/*global.JwtUser=claims*/
		application.Uid =claims.Id

		//ctx.SetLogoutFunc(core.Uid )

		ctx.Next()
	}
}

func TestJwt()  {
	j := iris_jwt.New(iris_jwt.Config{
		// Extractor属性可以选择从什么地方获取jwt进行验证，默认从http请求的header中的Authorization字段提取，也可指定为请求参数中的某个字段

		// 从请求参数token中提取
		// Extractor: jwt.FromParameter("token"),

		// 从请求头的Authorization字段中提取，这个是默认值
		Extractor: iris_jwt.FromAuthHeader,

		// 设置一个函数返回秘钥，关键在于return []byte("这里设置秘钥")
		ValidationKeyGetter: func(token *iris_jwt.Token) (interface{}, error) {
			return []byte("My Secret"), nil
		},

		// 设置一个加密方法
		SigningMethod: iris_jwt.SigningMethodHS256,
	})
	fmt.Println(j)
}
func GetJwt()  {
	// 简单示例：往jwt中写入了一对值注意哦这里可能永久有效
	token := iris_jwt.NewTokenWithClaims(iris_jwt.SigningMethodHS256, iris_jwt.MapClaims{
		"foo": "bar",
	})

	//示例2：添加更多参数满足我们需求 (设置过期时间)
	token = iris_jwt.NewTokenWithClaims(iris_jwt.SigningMethodHS256, iris_jwt.MapClaims{
		// 根据需求，可以存一些必要的数据
		"userName": "JabinGP",
		"userId":   "1",
		"admin":    true,

		// 签发人
		"iss": "iris",
		// 签发时间
		"iat": time.Now().Unix(),
		// 设定过期时间，便于测试，设置1分钟过期
		"exp": time.Now().Add(1 * time.Minute * time.Duration(1)).Unix(),
	})

	// 签名生成jwt字符串
	tokenString, _ := token.SignedString([]byte("My Secret"))
	fmt.Println(tokenString)
}

func ValidateJwt(ctx iris.Context)  {
	//输出jwt结构
	jwtInfo := ctx.Values().Get("jwt").(*iris_jwt.Token)
	fmt.Println(jwtInfo)
	//获取我们签发jwt写入的数据
	foo := jwtInfo.Claims.(iris_jwt.MapClaims)["foo"].(string)

	ctx.JSON(foo)
}

